Imports Microsoft.VisualBasic
Imports System
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Media
Imports System.Windows.Media.Imaging

Namespace Controls
	Public Class TiledBackground
		Inherits UserControl
		Private tiledImage As New Image()
		Private bitmap As BitmapImage
		Private lastWidth As Integer, lastHeight As Integer = 0
		Private sourceBitmap As WriteableBitmap

		Public Sub New()
			' create an image as the content of the control
			tiledImage.Stretch = Stretch.None
			Me.Content = tiledImage

			' no sizechanged to override
			AddHandler SizeChanged, AddressOf TiledBackground_SizeChanged
		End Sub

		Private Sub TiledBackground_SizeChanged(ByVal sender As Object, ByVal e As SizeChangedEventArgs)
			UpdateTiledImage()
		End Sub

		Private Sub UpdateTiledImage()
			If sourceBitmap IsNot Nothing Then
				Dim width As Integer = CInt(Fix(Math.Ceiling(Me.ActualWidth)))
				Dim height As Integer = CInt(Fix(Math.Ceiling(Me.ActualHeight)))

				' only regenerate the image if the width/height has grown
				If width < lastWidth AndAlso height < lastHeight Then
					Return
				End If
				lastWidth = width
				lastHeight = height

				Dim final As New WriteableBitmap(width, height)

				For x As Integer = 0 To final.PixelWidth - 1
					For y As Integer = 0 To final.PixelHeight - 1
						Dim tiledX As Integer = (x Mod sourceBitmap.PixelWidth)
						Dim tiledY As Integer = (y Mod sourceBitmap.PixelHeight)
						final.Pixels(y * final.PixelWidth + x) = sourceBitmap.Pixels(tiledY * sourceBitmap.PixelWidth + tiledX)
					Next y
				Next x

				tiledImage.Source = final
			End If
		End Sub

		#Region "SourceUri (DependencyProperty)"

		''' <summary>
		''' A description of the property.
		''' </summary>
		Public Property SourceUri() As Uri
			Get
				Return CType(GetValue(SourceUriProperty), Uri)
			End Get
			Set(ByVal value As Uri)
				SetValue(SourceUriProperty, value)
			End Set
		End Property
		Public Shared ReadOnly SourceUriProperty As DependencyProperty = DependencyProperty.Register("SourceUri", GetType(Uri), GetType(TiledBackground), New PropertyMetadata(Nothing, New PropertyChangedCallback(AddressOf OnSourceUriChanged)))

		Private Shared Sub OnSourceUriChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
			CType(d, TiledBackground).OnSourceUriChanged(e)
		End Sub

		Protected Overridable Sub OnSourceUriChanged(ByVal e As DependencyPropertyChangedEventArgs)
			bitmap = New BitmapImage(TryCast(e.NewValue, Uri))
			bitmap.CreateOptions = BitmapCreateOptions.None
			AddHandler bitmap.ImageOpened, AddressOf bitmap_ImageOpened
		End Sub

		Private Sub bitmap_ImageOpened(ByVal sender As Object, ByVal e As RoutedEventArgs)
			sourceBitmap = New WriteableBitmap(bitmap)
			UpdateTiledImage()
		End Sub

		#End Region
	End Class
End Namespace